//
//  CIFilterEffect.m
//  didacar
//
//  Created by 度周末网络-王腾 on 15/12/7.
//  Copyright © 2015年 dzmmac. All rights reserved.
//

#import "CIFilterEffect.h"
@interface CIFilterEffect ()

@property (nonatomic, strong, readwrite) UIImage *filterImage;
@property (nonatomic, strong, readwrite) UIImage *QRCodeImage;

@end

@implementation CIFilterEffect

- (instancetype)initWithImage:(UIImage *)image filterName:(NSString *)name
{
    self = [super init];
    if (self)
    {
        // 将UIImage转换成CIImage
        CIImage *ciImage = [[CIImage alloc] initWithImage:image];
        
        // 创建滤镜
        CIFilter *filter = [CIFilter filterWithName:name
                                      keysAndValues:kCIInputImageKey, ciImage, nil];
        [filter setDefaults];
        
        // 获取绘制上下文
        CIContext *context = [CIContext contextWithOptions:nil];
        
        // 渲染并输出CIImage
        CIImage *outputImage = [filter outputImage];
        
        // 创建CGImage句柄
        CGImageRef cgImage = [context createCGImage:outputImage
                                           fromRect:[outputImage extent]];
        
        _filterImage = [UIImage imageWithCGImage:cgImage];
        
        // 释放CGImage句柄
        CGImageRelease(cgImage);
    }
    return self;
}

#pragma mark - QRCodeGenerator
- (CIImage *)createQRForString:(NSString *)qrString {
    // Need to convert the string to a UTF-8 encoded NSData object
    NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
    // Create the filter
    CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
    // Set the message content and error-correction level
    [qrFilter setValue:stringData forKey:@"inputMessage"];
    [qrFilter setValue:@"H" forKey:@"inputCorrectionLevel"];
    // Send the image back
    return qrFilter.outputImage;
}

- (void)initWithQRCodeString:(NSString *)string width:(CGFloat)width reslutBlock:(CIFilterBlock)resultBlock
{
    
        self.resultBlock = resultBlock;
        __weak typeof(self) weakself = self;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            
            CIImage *outputImage = [weakself createQRForString:string];
    
            CIContext *context = [CIContext contextWithOptions:nil];
            CGImageRef cgImage = [context createCGImage:outputImage
                                               fromRect:[outputImage extent]];

            UIImage *image = [UIImage imageWithCGImage:cgImage
                                                 scale:0.1
                                           orientation:UIImageOrientationUp];
            
            // 不失真的放大
            UIImage *resized = [weakself resizeImage:image
                                         withQuality:kCGInterpolationNone
                                                rate:5.0];
            
            // 缩放到固定的宽度(高度与宽度一致)
            UIImage *qrCodeImage = [weakself scaleWithFixedWidth:width image:resized];
            
            // 为二维码增加色彩
            UIImage *customQrcode = [weakself imageBlackToTransparent:qrCodeImage withRed:51.0f andGreen:51.0f andBlue:51.0f];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                // 缩放到固定的宽度(高度与宽度一致)
                weakself.resultBlock(customQrcode);
                weakself.QRCodeImage = customQrcode;
                CGImageRelease(cgImage);
            });
        });
}

- (UIImage *)scaleWithFixedWidth:(CGFloat)width image:(UIImage *)image
{
    float newHeight = image.size.height * (width / image.size.width);
    CGSize size = CGSizeMake(width, newHeight);
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextTranslateCTM(context, 0.0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), image.CGImage);
    
    UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return imageOut;
}

- (UIImage *)resizeImage:(UIImage *)image
             withQuality:(CGInterpolationQuality)quality
                    rate:(CGFloat)rate
{
    UIImage *resized = nil;
    CGFloat width = image.size.width * rate;
    CGFloat height = image.size.height * rate;
    
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, quality);
    [image drawInRect:CGRectMake(0, 0, width, height)];
    resized = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return resized;
}

#pragma mark - imageToTransparent
void ProviderReleaseData (void *info, const void *data, size_t size){
    free((void*)data);
}
- (UIImage*)imageBlackToTransparent:(UIImage*)image withRed:(CGFloat)red andGreen:(CGFloat)green andBlue:(CGFloat)blue{
    const int imageWidth = image.size.width;
    const int imageHeight = image.size.height;
    size_t      bytesPerRow = imageWidth * 4;
    uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
    // create context
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,
                                                 kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
    CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
    // traverse pixe
    int pixelNum = imageWidth * imageHeight;
    uint32_t* pCurPtr = rgbImageBuf;
    for (int i = 0; i < pixelNum; i++, pCurPtr++){
        if ((*pCurPtr & 0xFFFFFF00) < 0x99999900){
            // change color
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[3] = red; //0~255
            ptr[2] = green;
            ptr[1] = blue;
        }else{
            uint8_t* ptr = (uint8_t*)pCurPtr;
            ptr[0] = 0;
        }
    }
    // context to image
    CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, ProviderReleaseData);
    CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight, 8, 32, bytesPerRow, colorSpace,
                                        kCGImageAlphaLast | kCGBitmapByteOrder32Little, dataProvider,
                                        NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease(dataProvider);
    UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef];
    // release
    CGImageRelease(imageRef);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    return resultUIImage;
}
@end
